Skip to content

refactor: evolve salt into raystack service framework#85

Open
ravisuhag wants to merge 30 commits intomainfrom
refactor/salt-evolution
Open

refactor: evolve salt into raystack service framework#85
ravisuhag wants to merge 30 commits intomainfrom
refactor/salt-evolution

Conversation

@ravisuhag
Copy link
Copy Markdown
Member

@ravisuhag ravisuhag commented Apr 18, 2026

Summary

Evolves salt from a bag of independent utilities into the standard way to build raystack services and CLIs. Drops unused packages, adds bootstrap entry points, modernizes dependencies.

18 packages, 52 files, 7060 lines. Down from 25+ packages.

Service bootstrap (app/)

app.Run(
    app.WithConfig(&cfg, config.WithFile("config.yaml")),
    app.WithLogger(slog.Default()),
    app.WithHTTPMiddleware(middleware.DefaultHTTP(slog.Default())),
    app.WithHandler("/api/", handler),
    app.WithAddr(cfg.Addr),
)

H2C and health check at /ping by default. No hidden middleware — everything is explicit.

CLI bootstrap (cli/)

rootCmd := &cobra.Command{Use: "frontier", Short: "identity management"}
rootCmd.AddCommand(serverCmd, configCmd)

cli.Init(rootCmd,
    cli.Version("0.1.0", "raystack/frontier"),
    cli.Topics(topics...),
)

cli.Execute(rootCmd)

Init adds help, completion, reference docs, and silences Cobra's default error/usage output. Execute runs the command and handles all errors with proper exit codes — sentinel errors (ErrSilent, ErrCancel), flag errors (with contextual usage), and general errors. Commands access shared output via cli.Output(cmd) and prompting via cli.Prompter(cmd).

Error handling

cli.Execute owns all error dispatch:

Error Behavior
cli.ErrSilent Exit 1, no output (command already printed)
cli.ErrCancel Exit 0, no output (user cancelled)
Flag errors Prints error + failing command's usage, exit 1
Other errors Prints "Error: ", exit 1

FlagError, HandleError, NewFlagError, and commander.IsCommandErr are removed — their functionality is internal to Init/Execute.

New packages

  • app/ — service lifecycle with graceful shutdown
  • cli/ — CLI lifecycle with Init + Execute
  • server/ — h2c HTTP server with health checks, timeouts, middleware support
  • middleware/ — recovery, requestid, requestlog, errorz, cors (Connect + HTTP)

Packages dropped (zero consumers)

Packages restructured

Old New
observability/ telemetry/
cli/terminator cli/terminal
cli/prompter cli/prompt
cli/releaser cli/version

Packages improved

  • config/ — upgraded validator v9→v10, replaced unmaintained go-defaults, removed stdout printing
  • cli/printer/ — rewritten as Output type (testable, writer-based)
  • cli/prompt/ — migrated from archived survey/v2 to charmbracelet/huh
  • server/ — read/write/idle timeouts, WithServer passthrough

Code modernization

  • interface{}any across all packages
  • os.IsNotExisterrors.Is(err, fs.ErrNotExist)
  • sort.Sliceslices.SortFunc
  • Cobra SilenceErrors/SilenceUsage set in Init (follows gh CLI pattern)

Dependencies

Removed: zap, logrus, survey/v2, tablewriter, oklog/run, safeexec, pkg/errors, go-defaults, sqlx, golang-migrate, dockertest

Added: connectrpc.com/connect, charmbracelet/huh, creasty/defaults

Upgraded: cobra v1.8→v1.10, validator v9→v10, glamour v0.3→v1.0, termenv v0.11→v0.16, spinner v1.18→v1.23, progressbar v3.8→v3.19

CI

golangci-lint v1.60→v2.11, Go 1.22→1.24, dropped errcheck linter.

Docs

Test plan

  • go build ./... passes
  • go vet ./... clean
  • golangci-lint run ./... — 0 issues
  • go test ./... — all pass
  • Verify on a real raystack project that migration works
  • End-to-end test with app.Run() and cli.Execute()

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant